package com.ruibo.modules.system.controller;

import com.ruibo.constants.UserConstants;
import com.ruibo.exception.BadRequestException;
import com.ruibo.utils.PageUtil;
import com.ruibo.utils.StringUtils;
import com.ruibo.config.DataScope;
import com.ruibo.modules.system.service.SysDeptService;
import com.ruibo.modules.system.service.SysPostService;
import com.ruibo.modules.system.service.SysRoleService;
import com.ruibo.modules.system.service.dto.SysUserDto;
import com.ruibo.modules.system.service.SysUserService;
import com.ruibo.modules.system.criteria.UserQueryCriteria;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * (SysUser)表控制层
 *
 * @author sunfeng
 * @since 2020-04-17 13:33:19
 */
@RestController
@RequestMapping("/system/sysUser")
@AllArgsConstructor
public class SysUserController {
    /**
     * 服务对象
     */

    private final SysUserService sysUserService;

    private final DataScope dataScope;

    private final SysDeptService sysDeptService;

    private final SysRoleService sysRoleService;

    private final SysPostService sysPostService;

    private final PasswordEncoder passwordEncoder;

    /**
     * 新增用户
     */


    @PostMapping
    @PreAuthorize("@el.check('system:user:add')")
    public ResponseEntity<Object> add(@Validated @RequestBody SysUserDto user) {

        if (UserConstants.NOT_UNIQUE.equals(sysUserService.checkUserNameUnique(user.getUserName()))) {
            throw new BadRequestException("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (UserConstants.NOT_UNIQUE.equals(sysUserService.checkPhoneUnique(user.getPhoneNumber()))) {
            throw new BadRequestException("新增用户'" + user.getPhoneNumber() + "'失败，手机号码已存在");
        }
        // 将密码加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));

        return new ResponseEntity<>(sysUserService.save(user), HttpStatus.OK);
    }

    /**
     * 修改用户
     */
    @PutMapping
    @PreAuthorize("@el.check('system:user:edit')")
    public ResponseEntity<Object> update(@Validated @RequestBody SysUserDto user) {

        /**
         * 这里有一个bug需要修改
         */
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return new ResponseEntity<>(sysUserService.update(user), HttpStatus.OK);
    }


    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("selectOne")
    public SysUserDto selectOne(Long id) {
        return this.sysUserService.queryById(id);
    }

    @GetMapping
    @PreAuthorize("@el.check('system:user:list')")
    public ResponseEntity<Object> getUsers(UserQueryCriteria criteria, Pageable pageable) {

        //存放部门id的集合
        Set<Long> deptSet = new HashSet<>();
        //
        Set<Long> result = new HashSet<>();
        if (!ObjectUtils.isEmpty(criteria.getDeptId())) {
            deptSet.add(criteria.getDeptId());
            // 获取部门的子部门id集合
            deptSet.addAll(dataScope.getDeptChildren(sysDeptService.findByPid(criteria.getDeptId())));
        }
        // 数据权限
        Set<Long> deptIds = dataScope.getDeptIds();
        // 查询条件不为空并且数据权限不为空则取交集
        if (!CollectionUtils.isEmpty(deptIds) && !CollectionUtils.isEmpty(deptSet)) {
            // 取交集
            result.addAll(deptSet);
            result.retainAll(deptIds);
            // 若无交集，则代表无数据权限
            criteria.setDeptIds(result);
            if (result.size() == 0) {
                return new ResponseEntity<>(PageUtil.toPage(null, 0), HttpStatus.OK);
            } else {
                return new ResponseEntity<>(sysUserService.queryAll(criteria, pageable), HttpStatus.OK);
            }
            // 否则取并集
        } else {
            result.addAll(deptSet);
            result.addAll(deptIds);
            criteria.setDeptIds(result);
            return new ResponseEntity<>(sysUserService.queryAll(criteria, pageable), HttpStatus.OK);
        }

    }

    /**
     * 状态修改
     */
    @PreAuthorize("@el.check('system:user:edit')")
    @PutMapping("/changeStatus")
    public ResponseEntity<Object> changeStatus(@RequestBody SysUserDto user) {
        return new ResponseEntity<>(sysUserService.update(user), HttpStatus.OK);
    }

    /**
     * 根据用户编号获取详细信息
     */
    @PreAuthorize("@el.check('system:user:query')")
    @GetMapping(value = {"/", "/{id}"})
    public ResponseEntity<Object> getInfo(@PathVariable(value = "id", required = false) Long id) {
        HashMap<String, Object> map = new HashMap<>();

        map.put("roles", sysRoleService.findAll());
        map.put("posts", sysPostService.findAll());
        if (StringUtils.isNotNull(id)) {
            map.put("data", sysUserService.queryById(id));
            map.put("postIds", sysPostService.selectPostListByUserId(id));
            // 根据用户id获取选取角色的列表
            map.put("roleIds", sysRoleService.selectRoleListByUserId(id));
        }
        return new ResponseEntity<>(map, HttpStatus.OK);
    }

    /**
     * 删除用户
     */
    @PreAuthorize("@el.check('system:user:remove')")
    @DeleteMapping("/{userIds}")
    public ResponseEntity<Object> remove(@PathVariable Long[] userIds) {
        sysUserService.deleteUserByIds(userIds);

        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 重置密码
     */
    @PutMapping("/resetPwd")
    @PreAuthorize("@el.check('system:user:edit')")
    public ResponseEntity resetPwd(@RequestBody SysUserDto user) {
        // 将密码加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return new ResponseEntity<>(sysUserService.update(user), HttpStatus.OK);
    }

}
